/*
 * Copyright (c) 2024 Huawei Technologies Co., Ltd.
 * openUBMC is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *         http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */

#ifndef MC_MANAGER_H
#define MC_MANAGER_H

#include <functional>
#include <map>
#include <mc/engine.h>
#include <mc/exception.h>
#include <mc/log.h>
#include <memory>
#include <mutex>
#include <string>
#include <variant>

// 包含具体的类定义
#include "internal/bus/bus_base/bus.h"
#include "internal/bus/bus_hisport/hisport.h"
#include "internal/bus/bus_i2c/i2c.h"
#include "internal/bus/bus_i2c_mux/i2c_mux.h"
#include "internal/chip/chip_base/chip.h"
#include "internal/chip/chip_eeprom/eeprom.h"
#include "internal/chip/chip_lm75/lm75.h"
#include "internal/chip/chip_pca9545/pca9545.h"
#include "internal/chip/chip_pca9555/pca9555.h"
#include "internal/chip/chip_ads78/ads78.h"


namespace dev {

/**
 * @brief 对象类型枚举
 */
enum class object_type {
    chip, // 芯片对象
    bus   // 总线对象
};

/**
 * @brief 设备管理器类（单例模式）
 *
 * 用于管理chip和bus对象的生命周期，提供创建、查询和删除功能
 * 全局只有一个实例，确保所有组件访问的是同一个管理器
 */
class MC_API device_manager {
public:
    /**
     * @brief 获取单例实例
     * @return device_manager的单例实例引用
     */
    static MC_API device_manager& get_instance();

    /**
     * @brief 析构函数
     */
    MC_API ~device_manager() = default;

    // 禁用复制构造和赋值
    device_manager(const device_manager&)            = delete;
    device_manager& operator=(const device_manager&) = delete;
    device_manager(device_manager&&)                 = delete;
    device_manager& operator=(device_manager&&)      = delete;

    /**
     * @brief 创建chip对象
     * @param object_name 对象名称
     * @param class_name 类名（如Pca9545、Chip等）
     * @param csr_data 配置数据
     * @return 创建的chip对象shared_ptr，失败返回nullptr
     */
    MC_API std::shared_ptr<chip_base> create_chip(const std::string& object_name,
                                                  const std::string& class_name,
                                                  mc::mutable_dict&  csr_data);

    /**
     * @brief 创建bus对象
     * @param object_name 对象名称
     * @param class_name 类名（如I2c、Hisport等）
     * @param csr_data 配置数据
     * @return 创建的bus对象shared_ptr，失败返回nullptr
     */
    MC_API std::shared_ptr<bus_base> create_bus(const std::string& object_name,
                                                const std::string& class_name,
                                                mc::mutable_dict&  csr_data);

    /**
     * @brief 根据名称和类型查询对象
     * @param name 对象名称
     * @param type 对象类型
     * @return 找到的对象shared_ptr，没找到返回nullptr
     */
    MC_API std::variant<std::shared_ptr<chip_base>, std::shared_ptr<bus_base>>
           find_object(const std::string& name, object_type type);

    /**
     * @brief 根据名称删除对象
     * @param name 对象名称
     * @param type 对象类型
     * @return 删除成功返回true，失败返回false
     */
    MC_API bool remove_object(const std::string& name, object_type type);

    /**
     * @brief 获取chip对象表
     * @return chip对象表的引用
     */
    MC_API const std::map<std::string, std::shared_ptr<chip_base>>& get_chip_table() const {
        std::lock_guard<std::mutex> lock(m_mutex);
        return m_chip_table;
    }

    /**
     * @brief 获取bus对象表
     * @return bus对象表的引用
     */
    MC_API const std::map<std::string, std::shared_ptr<bus_base>>& get_bus_table() const {
        std::lock_guard<std::mutex> lock(m_mutex);
        return m_bus_table;
    }

    /**
     * @brief 清空所有对象表
     */
    MC_API void clear_all();

private:
    // 私有构造函数，防止外部创建实例
    device_manager();

    // 工厂函数类型定义
    using chip_factory_func = std::function<std::shared_ptr<chip_base>(mc::mutable_dict&)>;
    using bus_factory_func  = std::function<std::shared_ptr<bus_base>(mc::mutable_dict&)>;

    // 初始化工厂映射表
    void init_factory_maps();

    std::map<std::string, std::shared_ptr<chip_base>> m_chip_table; // chip对象管理表
    std::map<std::string, std::shared_ptr<bus_base>>  m_bus_table;  // bus对象管理表

    std::map<std::string, chip_factory_func> m_chip_factories; // chip工厂函数映射表
    std::map<std::string, bus_factory_func>  m_bus_factories;  // bus工厂函数映射表

    mutable std::mutex m_mutex; // 线程安全锁
};

} // namespace dev

// 使用示例：
//
// // 获取单例实例
// auto& manager = dev::device_manager::get_instance();
//
// // 创建chip对象
// mc::mutable_dict csr_data;
// csr_data["Address"] = 0x70;
// auto chip = manager.create_chip("my_pca9545", "Pca9545", csr_data);
//
// // 创建bus对象
// mc::mutable_dict bus_data;
// bus_data["Id"] = 1;
// auto bus = manager.create_bus("my_i2c", "I2c", bus_data);
//
// // 查找对象
// auto found_chip = manager.find_object("my_pca9545", dev::object_type::chip);
// auto found_bus = manager.find_object("my_i2c", dev::object_type::bus);
//
// // 删除对象
// manager.remove_object("my_pca9545", dev::object_type::chip);
//
// // 清空所有对象
// manager.clear_all();

#endif // MC_MANAGER_H